#include <stdio.h>
#include <assert.h>
#include "thread.h"
#include "mutex.h"

/*
 * Test des mutex.
 *
 * Les affichages doivent se faire dans le bon ordre.
 */

thread_mutex_t * mutex;

struct thfuncargs {
  char * tab;
  int ltab;
  char c;
};

static void * thfunc(void * dummy)
{
  int i;
  struct thfuncargs * thfcargs = (struct thfuncargs *)dummy;

  thread_mutex_lock(mutex);
  // Section critique
  printf("Le thread %p a pris la main\n", thread_self());
  for (i = 0; i < thfcargs->ltab; i++)
  {
    thfcargs->tab[i] = thfcargs->c;
    printf("thread_yield()\n");
    thread_yield();
  }
  printf("Le thread %p a rendu la main\n", thread_self());
  thread_mutex_unlock(mutex);

  thread_exit(NULL);
}

int main(void)
{
  thread_t th1, th2;
  int err;
  int ltab = 10;
  char tab[ltab];

  struct thfuncargs thfcargs1;
  thfcargs1.tab = tab;
  thfcargs1.ltab = ltab;
  thfcargs1.c = 'a';
  struct thfuncargs thfcargs2;
  thfcargs2.tab = tab;
  thfcargs2.ltab = ltab;
  thfcargs2.c = 'b';

  thread_mutex_init(&mutex);

  err = thread_create(&th1, thfunc, &thfcargs1);
  assert(!err);
  err = thread_create(&th2, thfunc, &thfcargs2);
  assert(!err);

  err = thread_join(th2, NULL);
  assert(!err);
  err = thread_join(th1, NULL);
  assert(!err);

  thread_mutex_destroy(mutex);

  return 0;
}
